"""
生成器实现协程

用同步的方式编写异步的代码，在适当的时候暂停函数并在适当的时候启动函数。

协程的调度模式：
    1.事件循环 + 协程

协程是单线程模式。
"""

import inspect
import socket
from selectors import DefaultSelector

selector = DefaultSelector()


def gen_func():
    # 返回值给调用方
    # 调用方通过send方式返回值给生成器
    value = yield 1
    return "Tesla"


def use_gen_func():
    gen = gen_func()

    # 获取生成器的状态
    print(inspect.getgeneratorstate(gen))

    print(gen.send(None))

    # 获取生成器的状态
    print(inspect.getgeneratorstate(gen))

    try:
        print(gen.send(None))
    except StopIteration as e:
        pass
    # 获取生成器的状态
    print(inspect.getgeneratorstate(gen))
    # 输出结果：
    """
    GEN_CREATED
    1
    GEN_SUSPENDED
    GEN_CLOSED
    """


def get_socket_data():
    yield "Apple"


def downloader(url):
    """
    伪代码（用同步的方式编写异步的代码）
    """

    # 建立Socket连接
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 启用非阻塞
    client.setblocking(False)

    # connect阻塞不会消耗CPU
    try:
        client.connect(("127.0.0.1", 80))
    except BlockingIOError as e:
        pass

    # 注册
    # selector.register(client.fileno(), EVENT_WRITE, connected)
    source = yield from get_socket_data()

    data = source.decode("utf8")
    # 通过两个回车换行符去掉头部信息
    html_data = data.split("\r\n\r\n")[1]
    print(html_data)


def download_html(html):
    html = yield from downloader()


if __name__ == '__main__':
    use_gen_func()
